<?php

namespace Music\Controller;

use Think\Controller;

class PayController extends Controller {

	protected function _initialize(){
		
		if($_SERVER['REQUEST_METHOD'] != 'POST'){
			#self::return_err('error request method');
		}
		
		//微信支付参数配置(appid,商户号,支付秘钥)
		$config = array(
			'appid'		 => 'wxc6cfe9e7f97b9edf',
			'pay_mchid'	 => '1502182731',
			'pay_apikey' => '85d77f4b18771551f1f1cd06c391570a'
		);
		$this->config = $config;
	}
	
	public function info(){
		
		$m_log =M('log');
	
		$data = $m_log->find(37);
		$datas = unserialize($data['xml']);
		
		$data =  self::xml2array($datas);
		
		dump($datas);
		dump($data);
	}
	
	
	/**
     * 预支付请求接口(POST)
     * @param string $openid 	openid
     * @param string $body 		商品简单描述
     * @param string $order_sn  订单编号
     * @param string $total_fee 金额
     * @return  json的数据
     */
	public function prepay(){
		$config = $this->config;
		$m_log = M("log");
		
		$openid = I('post.openid');
		$body = I('post.body');
		$order_sn = I('post.order_sn');
		$total_fee = I('post.total_fee');
		
		//统一下单参数构造
		$unifiedorder = array(
			'appid'			=> $config['appid'],
			'mch_id'		=> $config['pay_mchid'],
			'nonce_str'		=> self::getNonceStr(),
			'body'			=> $body,
			'out_trade_no'	=> $order_sn,
			'total_fee'		=> $total_fee * 100,
			'spbill_create_ip'	=> get_client_ip(),
			'notify_url'	=> 'http://'.$_SERVER['HTTP_HOST'].'/Music/Pay/notify',
			'trade_type'	=> 'JSAPI',
			'openid'		=> $openid
		);
		$unifiedorder['sign'] = self::makeSign($unifiedorder);
		//请求数据
		$xmldata = self::array2xml($unifiedorder);
		$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $res = self::curl_post_ssl($url, $xmldata);
		
        if(!$res){
			self::return_err("Can't connect the server");
        }
		
		// 这句 file_put_contents 是用来查看服务器返回的结果 测试完可以删除了
		#file_put_contents(APP_ROOT.'/Statics/log1.txt',$res,FILE_APPEND);
		
		$content = self::xml2array($res);
		
		$log_map['xml'] = "22-".json_encode($content);
			$m_log->add($log_map);
		
		if(strval($content['result_code']) == 'FAIL'){
			self::return_err(strval($content['err_code_des']));
        }
		if(strval($content['return_code']) == 'FAIL'){
			self::return_err(strval($content['return_msg']));
        }
        self::return_data(array('data'=>$content));
		#$this->ajaxReturn($content);
	}
	
	
	/**
     * 进行支付接口(POST)
     * @param string $prepay_id 预支付ID(调用prepay()方法之后的返回数据中获取)
     * @return  json的数据
     */
	public function pay(){
		$config = $this->config;
		$prepay_id = I('post.prepay_id');
		
		$data = array(
			'appId'		=> $config['appid'],
			'timeStamp'	=> time(),
			'nonceStr'	=> self::getNonceStr(),
			'package'	=> 'prepay_id='.$prepay_id,
			'signType'	=> 'MD5'
		);
		
		$data['paySign'] = self::makeSign($data);
		
		$this->ajaxReturn($data);
	}
	
	//微信支付回调验证
	public function notify(){
		$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
		$m_log = M("log");
		
		//监控回调信息
		
		// 这句file_put_contents是用来查看服务器返回的XML数据 测试完可以删除了
		//file_put_contents(APP_ROOT.'/Statics/log2.txt',$res,FILE_APPEND);
		
		//将服务器返回的XML数据转化为数组
		$data = self::xml2array($xml);
		
		// 保存微信服务器返回的签名sign
		$data_sign = $data['sign'];
		
		// sign不参与签名算法
		unset($data['sign']);
		$sign = self::makeSign($data);
		
		// 判断签名是否正确  判断支付状态
		if ( ($sign===$data_sign) && ($data['return_code']=='SUCCESS') && ($data['result_code']=='SUCCESS') ) {
			$m_pay_order = M("pay_order");
			$m_common_user = M("common_user");
			$m_mall_content = M("mall_content");
			$m_mall_order = M("mall_order");
			$m_mall_content_money = M("mall_content_money");
			
			$user_map['weixin_openid'] =  $data['openid'];
			$user_data = $m_common_user->where($user_map)->find();
			
			$pay_order_map['form_order_id'] = $data['out_trade_no'];
			$pay_order_map['uid'] = $user_data['id'];
			$pay_order_data = $m_mall_order->where($pay_order_map)->find();
			#判断商品是否还有库存 
			$goods_map['id'] = $pay_order_data['goods_id'];
			$goods_data = $m_mall_content->where($goods_map)->find();
			
			if($pay_order_data['goods_type_id'] == 0){
				$inventory = $goods_data['inventory'];
				$money = $goods_data['money'];
			}else{
				$money_map['id'] = $pay_order_data['goods_type_id'];
				$money_data = $m_mall_content_money->where($money_map)->find();
				$inventory = $money_data['number'];
				$money = $money_data['goods_money'];
			}
			
			if($inventory >= 1){
				#判断价格是否一致
				if($money*100 == $data['total_fee']){
					
					$result = $data;
					//获取服务器返回的数据
					$order_sn = $data['out_trade_no'];			//订单单号
					$openid = $data['openid'];					//付款人openID
					$total_fee = $data['total_fee'];			//付款金额
					$transaction_id = $data['transaction_id']; 	//微信支付流水号
					
					//更新数据库
					$this->updateDB($order_sn,$openid,$total_fee,$transaction_id);
					
				}else{
					$result = false;
				}
			}else{
				$result = false;
			}
			
		}else{
			$result = false;
		}
		//返回状态给微信服务器
		//$result = false;
		if ($result) {
			$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
		}else{
			$str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
		}
	
		echo $str;
		return $result;
	}
	
	
	/* 
	*支付完成回调
	* $order_sn    订单单号
	* $openid    付款人openID
	* $total_fee    付款金额
	* $transaction_id    微信支付流水号
	*/
	
	public function updateDB($order_sn,$openid,$total_fee,$transaction_id){
	#public function updateDB(){
		/* $openid = 'oeWhV43GJdJV1hHW5Ab142TozFRc';
		$order_sn = '180514000081';
		$total_fee = '0.01';
		$transaction_id = 'weixin_123123'; */
		
		
		$m_mall_content = M("mall_content");
		$m_pay_order = M("pay_order");
		$m_mall_order = M("mall_order");
		$m_common_user = M("common_user");
		$m_mall_content_img = M("mall_content_img");
		$m_cms_style = M("cms_style");
		$m_mall_money = M("mall_money");
		$m_mall_content_money = M("mall_content_money");
		
		#查询用户详情
		$user_map['weixin_openid'] = $openid;
		$user_data = $m_common_user->where($user_map)->find();
		
		#修改pay_order表
		$pay_order_map['order_id'] = $order_sn;
		$pay_order_map['status'] = 2;
		$pay_order_datas['status'] = 1;
		$pay_order_datas['transaction_id'] = $transaction_id;
		
		$dingdan = $m_pay_order->where($pay_order_map)->find();
		$m_pay_order->where($pay_order_map)->save($pay_order_datas);
		if($dingdan){
			#pay_order详情
			$pay_order_map['status'] = 1;
			$pay_order_data = $m_pay_order->where($pay_order_map)->find();
			
			
			#修改 mall_order 表
			$mall_order_map['form_order_id'] = $order_sn;
			$mall_order_map['status'] = 2;
			$mall_order_datas['status'] = 1;
			$m_mall_order->where($mall_order_map)->save($mall_order_datas);
			
			#mall_order 详情
			$mall_order_map['status'] = 1;
			$mall_order_data = $m_mall_order->where($mall_order_map)->find();
			
			//商品详情
			$goods_map['id'] = $mall_order_data['goods_id'];
			$goods_data = $m_mall_content->where($goods_map)->find();
			
			#卖方用户详情
			$goods_user_map['id'] = $goods_data['uid'];
			$goods_user_data = $m_common_user->where($goods_user_map)->find();
			
			#判断是专辑、二手专辑、活动
			if($goods_data['type'] == 16 or $goods_data['type'] == 22){
				#专辑
				#给该专辑做库存处理，
				$m_mall_content->where($goods_map)->setInc("sale");
				$m_mall_content->where($goods_map)->setDec("inventory");
				
				#查询库存 若为1 卖出后为0 则修改商品状态
				if($goods_data['inventory'] <= 1){
					if($goods_data['type'] == 16){
						$order_status = 5;
					}else{
						$order_status = 3;
					}
					$order_status_data['status'] = $order_status;     //表示售罄
					$m_mall_content->where($goods_map)->save($order_status_data);
				}
				
				#买方支出记录
				$mall_money_data['uid'] = $user_data['id'];
				$mall_money_data['type'] = 2;
				$mall_money_data['order_type'] = 2;
				$mall_money_data['type_value'] = "微信购买专辑";
				$mall_money_data['begin_money'] = $user_data['money'];
				$mall_money_data['money'] = $pay_order_data['money'];
				$mall_money_data['end_money'] = $user_data['money'];
				$mall_money_data['value'] = $order_sn;
				$mall_money_data['time'] = time();
				$mall_money_data['ip'] = get_client_ip();
				$mall_money_data['status'] = 1;
				$res = $m_mall_money->add($mall_money_data);
				
				#卖放收入记录
				$mall_money_data['uid'] = $goods_data['uid'];
				$mall_money_data['type'] = 1;
				$mall_money_data['order_type'] = 3;
				$mall_money_data['type_value'] = "卖出专辑专辑";
				$mall_money_data['begin_money'] = $goods_user_data['money'];
				$mall_money_data['money'] = $pay_order_data['money'];
				$mall_money_data['end_money'] = $goods_user_data['money'] + $pay_order_data['money'];
				$mall_money_data['value'] = $order_sn;
				$mall_money_data['time'] = time();
				$mall_money_data['ip'] = get_client_ip();
				$mall_money_data['status'] = 1;
				$res = $m_mall_money->add($mall_money_data);
				#卖方增加余额
				$user_goods_money = $m_common_user->where($goods_user_map)->setInc("money",$pay_order_data['money']);
				
				#生成专辑
				$goods_data['uid'] = $user_data['id'];
				$goods_data['type'] = 22;
				$goods_data['time'] = time();
				$goods_data['inventory'] = 1;
				$goods_data['original_money'] = $goods_data['money'];
				$goods_data['sale'] = 0;
				$goods_data['status'] = 2;
				unset($goods_data['id']);
				$my_goods_result = $m_mall_content->add($goods_data);
				
				#创建风格关联
				$add_style_array = explode(',',$goods_data['style']);
				
				foreach($add_style_array as $i=>$v){
					if($add_style_array[$i]){
						$add_style_app['style_id'] = $add_style_array[$i];
						$add_style_app['style_table'] = 2;
						$add_style_app['music_id'] = $my_goods_result;
						$m_cms_style->add($add_style_app);
					}
				}
				
				#查询专辑下歌曲
				$my_goods_song['form_id'] = $goods_map['id'];
				$my_goods_song['type'] = 17;
				$my_goods_song['status'] = 1;
				$my_goods_list = $m_mall_content->where($my_goods_song)->select();
				
				foreach($my_goods_list as $i=>$v){
					#查询歌曲图片并且重新添加
					$my_img_map['type'] = array("in",'2,3');
					$my_img_map['status'] = 1;
					$my_img_map['form_id'] = $my_goods_list[$i]['id'];
					$my_img_list = $m_mall_content_img->where($my_img_map)->select();
					
					$my_goods_list[$i]['form_id'] = $my_goods_result;
					unset($my_goods_list[$i]['id']);
					
					$my_img_result = $m_mall_content->add($my_goods_list[$i]);
					
					foreach($my_img_list as $ii=>$vv){
						unset($my_img_list[$ii]['id']);
						$my_img_list[$ii]['form_id'] = $my_img_result;
						$m_mall_content_img->add($my_img_list[$ii]);
					}
				}
				
				
			}elseif($goods_data['type'] == 19){
				#活动
				
				#买方支出记录
				$mall_money_data['uid'] = $user_data['id'];
				$mall_money_data['type'] = 2;
				$mall_money_data['order_type'] = 2;
				$mall_money_data['type_value'] = "微信购买活动";
				$mall_money_data['begin_money'] = $user_data['money'];
				$mall_money_data['money'] = $pay_order_data['money'];
				$mall_money_data['end_money'] = $user_data['money'];
				$mall_money_data['value'] = $order_sn;
				$mall_money_data['time'] = time();
				$mall_money_data['ip'] = get_client_ip();
				$mall_money_data['status'] = 1;
				$res = $m_mall_money->add($mall_money_data);
				
				#卖放收入记录
				$mall_money_data['uid'] = $goods_data['uid'];
				$mall_money_data['type'] = 1;
				$mall_money_data['order_type'] = 3;
				$mall_money_data['type_value'] = "卖出活动门票";
				$mall_money_data['begin_money'] = $goods_user_data['money'];
				$mall_money_data['money'] = $pay_order_data['money'];
				$mall_money_data['end_money'] = $goods_user_data['money'] + $pay_order_data['money'];
				$mall_money_data['value'] = $order_sn;
				$mall_money_data['time'] = time();
				$mall_money_data['ip'] = get_client_ip();
				$mall_money_data['status'] = 1;
				$res = $m_mall_money->add($mall_money_data);
				#卖方增加余额
				$user_goods_money = $m_common_user->where($goods_user_map)->setInc("money",$pay_order_data['money']);
				#echo "成功";
				#生成二维码
				$erweima_url = scerweima($order_sn);
				$url_order_map['form_order_id'] = $order_sn;
				$url_order_map['status'] = 1;
				$url_order_datas['goods_time'] = trim($erweima_url,'.');
				$m_mall_order->where($url_order_map)->save($url_order_datas);
				
				#库存
				$kucun_map['id'] = $mall_order_data['goods_type_id'];
				$m_mall_content_money->where($kucun_map)->setDec("number");
				
				
			}
			
			#修改订单状态，完成订单
			
			#添加我的收入记录   卖方的收入记录
			
			
			#专辑和二手专辑需要生成我的专辑
			
			
		}
		
	}
	
	
	
	
//---------------------------------------------------------------用到的函数------------------------------------------------------------
	/**
     * 错误返回提示
     * @param string $errMsg 错误信息
     * @param string $status 错误码
     * @return  json的数据
     */
	protected function return_err($errMsg='error',$status=0){
		exit(json_encode(array('status'=>$status,'result'=>'fail','errmsg'=>$errMsg)));
	}
	
	
	/**
     * 正确返回
     * @param 	array $data 要返回的数组
     * @return  json的数据
     */
	protected function return_data($data=array()){
		exit(json_encode(array('status'=>1,'result'=>'success','data'=>$data)));
	}
  
	/**
     * 将一个数组转换为 XML 结构的字符串
     * @param array $arr 要转换的数组
     * @param int $level 节点层级, 1 为 Root.
     * @return string XML 结构的字符串
     */
    protected function array2xml($arr, $level = 1) {
        $s = $level == 1 ? "<xml>" : '';
        foreach($arr as $tagname => $value) {
            if (is_numeric($tagname)) {
                $tagname = $value['TagName'];
                unset($value['TagName']);
            }
            if(!is_array($value)) {
                $s .= "<{$tagname}>".(!is_numeric($value) ? '<![CDATA[' : '').$value.(!is_numeric($value) ? ']]>' : '')."</{$tagname}>";
            } else {
                $s .= "<{$tagname}>" . $this->array2xml($value, $level + 1)."</{$tagname}>";
            }
        }
        $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
        return $level == 1 ? $s."</xml>" : $s;
    }
	
	/**
	 * 将xml转为array
	 * @param  string 	$xml xml字符串
	 * @return array    转换得到的数组
	 */
	protected function xml2array($xml){   
		//禁止引用外部xml实体
		libxml_disable_entity_loader(true);
		$result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);        
		return $result;
	}
	
	/**
	 * 
	 * 产生随机字符串，不长于32位
	 * @param int $length
	 * @return 产生的随机字符串
	 */
	protected function getNonceStr($length = 32) {
		$chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
		$str ="";
		for ( $i = 0; $i < $length; $i++ )  {  
			$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
		} 
		echo $str;
		return $str;
	}
	
	/**
	* 生成签名
	* @return 签名
	*/
	protected function makeSign($data){
		//获取微信支付秘钥
		$key = $this->config['pay_apikey'];
		// 去空
		$data=array_filter($data);
		//签名步骤一：按字典序排序参数
		ksort($data);
		$string_a=http_build_query($data);
		$string_a=urldecode($string_a);
		//签名步骤二：在string后加入KEY
		//$config=$this->config;
		$string_sign_temp=$string_a."&key=".$key;
		//签名步骤三：MD5加密
		$sign = md5($string_sign_temp);
		// 签名步骤四：所有字符转为大写
		$result=strtoupper($sign);
		return $result;
	}
	
	/**
	 * 微信支付发起请求
	 */
	protected function curl_post_ssl($url, $xmldata, $second=30,$aHeader=array()){
		$ch = curl_init();
		//超时时间
		curl_setopt($ch,CURLOPT_TIMEOUT,$second);
		curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
		//这里设置代理，如果有的话
		//curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
		//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
		curl_setopt($ch,CURLOPT_URL,$url);
		curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
		curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
		
	 
		if( count($aHeader) >= 1 ){
			curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
		}
	 
		curl_setopt($ch,CURLOPT_POST, 1);
		curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata);
		$data = curl_exec($ch);
		if($data){
			curl_close($ch);
			return $data;
		}
		else { 
			$error = curl_errno($ch);
			echo "call faild, errorCode:$error\n"; 
			curl_close($ch);
			return false;
		}
	}
	
	
}


